/**
 *  编写代码, 实现阻塞队列案例 (循环优先级阻塞队列).
 */

class MyBlockingQueue {
    private final int DEFAULT_CAPACITY = 20; // 数组默认容量.
    public int[] elem = new int[DEFAULT_CAPACITY]; // 阻塞队列以数组实现.
    private volatile int head = 0; // 永远指向队首位置.
    private volatile int tail = 0; // 永远指向队尾元素的下一个位置.
    public volatile int size = 0; // 阻塞队列中的有效数据个数.

    public void put(int val) throws InterruptedException {
        synchronized (this) {
            while(size >= elem.length) {
                this.wait();
            }
            elem[tail] = val;
            tail++;
            tail = tail % elem.length;
            size++;
            this.notify();
        }
    }

    public Integer take() throws InterruptedException {
        synchronized (this) {
            while (size == 0) {
                this.wait();
            }
            Integer top = elem[head]; // 出队首元素.
            head++;
            head = head % elem.length;
            size--;
            this.notify();

            return top;
        }
    }
}

public class Test1 {
    public static void main(String[] args) {
        MyBlockingQueue queue = new MyBlockingQueue();

        Thread produce = new Thread(() -> {
            int count = 1;
            while(true) {
                try {
                    queue.put(count);
                    System.out.println("成产了元素: " + count);
                    count++;
                    Thread.sleep(500);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });

        Thread customer = new Thread(() -> {
            while (true) {
                try {
                    Integer result = queue.take();
                    System.out.println("消费了元素: " + result);
                    //Thread.sleep(500);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });

        produce.start();
        customer.start();
    }
}
